package com.springsecirtytest.activiti1.controller;

import com.springsecirtytest.activiti1.SecurityUtil;
import com.springsecirtytest.activiti1.mapper.ActivitiMaper;
import com.springsecirtytest.activiti1.util.AjaxResponse;
import com.springsecirtytest.activiti1.util.GlobalConfig;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.FormProperty;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.plugin.javascript.navig.Link;

import java.security.PrivateKey;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/task")
public class TaskController {

    @Autowired
    private SecurityUtil securityUtil;
    @Autowired
    private TaskRuntime taskRuntime;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessRuntime processRuntime;

    @Autowired
    private ActivitiMaper mapper;

    //查询任务
    @GetMapping(value = "/getTasks")
    public AjaxResponse getTasks() {

        if (GlobalConfig.Test) {
            securityUtil.logInAs("bajie");
        }
        Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 100));

        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        for (Task tk : tasks.getContent()) {
            HashMap<String, Object> hashMap = new HashMap<>();

            hashMap.put("id", tk.getId());
            hashMap.put("name", tk.getName());
            hashMap.put("status", tk.getStatus());
            hashMap.put("createDate", tk.getCreatedDate());
            if (tk.getAssignee() == null) {
                hashMap.put("assignee", "待拾取任务");
            } else {
                hashMap.put("assignee", tk.getAssignee());
            }

            ProcessInstance processInstance = processRuntime.processInstance(tk.getProcessInstanceId());
            hashMap.put("instancename", processInstance.getName());
            list.add(hashMap);

        }
        return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.SUCCESS.getCode()
                , GlobalConfig.ResponseCode.SUCCESS.getDesc()
                , list);
    }

    //完成待办任务
    @GetMapping(value = "/completeTask")
    public AjaxResponse completeTask(@RequestParam("taskID") String taskID) {
        if (GlobalConfig.Test) {
            securityUtil.logInAs("bajie");
        }
        Task task = taskRuntime.task(taskID);
        if (task.getAssignee() == null) {
            taskRuntime.claim(TaskPayloadBuilder
                    .claim()
                    .withTaskId(task.getId())
                    .build());
        }
        Task complete = taskRuntime.complete(TaskPayloadBuilder
                .complete()
                .withTaskId(taskID)
                .build());

        return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.SUCCESS.getCode()
                , GlobalConfig.ResponseCode.SUCCESS.getDesc()
                , task);
    }

    //渲染表单
    @GetMapping(value = "/formDataShow")
    public AjaxResponse formDataShow(@RequestParam("taskID") String taskID) {

        if (GlobalConfig.Test) {
            securityUtil.logInAs("bajie");
        }
        Task task = taskRuntime.task(taskID);

        HashMap<String, String> controlistMap= new HashMap<>();

        List<HashMap<String, Object>> tempControlList = mapper.selectFormData(task.getProcessInstanceId());

        for (HashMap ls :tempControlList){

            controlistMap.put(ls.get("Control_ID_").toString(),ls.get("Control_VALUE_").toString());
        }

        UserTask userTask = (UserTask) repositoryService.getBpmnModel(task.getProcessDefinitionId())
                //这里其实要传的的是任务的key，但是我们拿不到任务的key值，故我们要把表单的key值和任务的key值设置一致
                .getFlowElement(task.getFormKey());

        if (userTask == null) {
            return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.SUCCESS.getCode()
                    , GlobalConfig.ResponseCode.SUCCESS.getDesc()
                    , "无表单");
        }

        List<FormProperty> formProperties = userTask.getFormProperties();
        List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();
        for (FormProperty fp : formProperties) {
            String[] splitFP = fp.getId().split("-_!");

            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", splitFP[0]);
            hashMap.put("controlType", splitFP[1]);
            hashMap.put("controlLable", splitFP[2]);
            hashMap.put("controlIsParam", splitFP[4]);

            //默认值如果是表单控件ID
            if (splitFP[3].startsWith("FormProperty_")) {
                //控件ID存在
                if (controlistMap.containsKey(splitFP[3])) {
                    hashMap.put("controlDefValue", controlistMap.get(splitFP[3]));
                } else {
                    //控件ID不存在
                    hashMap.put("controlDefValue", "读取失败，检查" + splitFP[0] + "配置");
                }
            } else {
                //默认值如果不是表单控件ID则写入默认值
                hashMap.put("controlDefValue", splitFP[3]);
            }


            hashMap.put("controlIsParam", splitFP[4]);
            listMap.add(hashMap);
        }


        return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.SUCCESS.getCode()
                , GlobalConfig.ResponseCode.SUCCESS.getDesc()
                , listMap);

    }

    //提交表单完成任务写入数据库
    @PostMapping(value = "/formDataSave")
    public AjaxResponse formDataSave(@RequestParam("taskID") String taskID,
                                     @RequestParam("formData") String formData) throws ParseException {

        if (GlobalConfig.Test) {
            securityUtil.logInAs("bajie");
        }

        Task task = taskRuntime.task(taskID);

        //formData:控件id-_!控件值-_!是否参数!_!控件id-_!控件值-_!是否参数
        //FormProperty_0lovri0-_!不是参数-_!f!_!FormProperty_1iu6onu-_!数字参数-_!s

        HashMap<String, Object> variables = new HashMap<String, Object>();
        Boolean hasVariables = false;//没有任何参数

        List<HashMap<String, Object>> listMap = new ArrayList<>();

        //前端传来的字符串，拆分成每个控件
        String[] formDataList = formData.split("!_!");//
        for (String controlItem : formDataList) {
            String[] formDataItem = controlItem.split("-_!");

            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("PROC_DEF_ID_", task.getProcessDefinitionId());
            hashMap.put("PROC_INST_ID_", task.getProcessInstanceId());
            hashMap.put("FORM_KEY_", task.getFormKey());
            hashMap.put("Control_ID_", formDataItem[0]);
            hashMap.put("Control_VALUE_", formDataItem[1]);
            hashMap.put("Control_PARAM_", formDataItem[2]);
            listMap.add(hashMap);

            //构建参数集合
            switch (formDataItem[2]) {
                case "f":
                    System.out.println("控件值不作为参数");
                    break;
                case "s":
                    variables.put(formDataItem[0], formDataItem[1]);
                    hasVariables = true;
                    break;
                case "t":
                    SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    variables.put(formDataItem[0], timeFormat.parse(formDataItem[2]));
                    hasVariables = true;
                    break;
                case "b":
                    variables.put(formDataItem[0], BooleanUtils.toBoolean(formDataItem[2]));
                    hasVariables = true;
                    break;
                default:
                    System.out.println("控件参数类型配置错误：" + formDataItem[0] + "的参数类型不存在，" + formDataItem[2]);
            }


           if (hasVariables) {
                //带参数完成任务
               Task complete = taskRuntime.complete(TaskPayloadBuilder
                       .complete()
                       .withTaskId(taskID)
                       .withVariables(variables)
                       .build());
           } else {
               Task complete = taskRuntime.complete(TaskPayloadBuilder
                       .complete()
                       .withTaskId(taskID)
                       .build());
           }
        }
        int result = mapper.insertFormData(listMap);
        return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap);
        /*} catch (Exception f) {
            return AjaxResponse.ajaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "失败", e.toString());
        }*/
    }

}